﻿using System;
using System.Linq;

namespace OrmSmackdown.EntityFrameworks
{
    public class Aggregate : IAggregate
    {
        private string _connectionInformation;
        OrmSmackdown.EntityFrameworks.Mappings.efSmackDownEntities _ctx;

        public Aggregate(string connectionInformation)
        {
            _connectionInformation = connectionInformation;
            _ctx = new OrmSmackdown.EntityFrameworks.Mappings.efSmackDownEntities(_connectionInformation);
        }

        public void InsertRecordsApproachOne(int recordsToInsert)
        {
            _ctx.Connection.Open();
            using (var trans = _ctx.Connection.BeginTransaction())
            {
                for (var idx = 0; idx < recordsToInsert; ++idx)
                {
                    var perf = new Mappings.Performance() { MilliSeconds = idx, Action = Constants.STR_AggregateCount, OrmName = "NHibernate" };
                    _ctx.AddToPerformance(perf);
                }

                _ctx.SaveChanges();

                trans.Commit();
            }
            _ctx.Connection.Close();
        }

        public void InsertRecordsApproachTwo(int recordsToInsert)
        {
            for (var idx = 0; idx < recordsToInsert; ++idx)
            {
                var perf = new Mappings.Performance() { MilliSeconds = idx, Action = Constants.STR_AggregateCount, OrmName = "NHibernate" };
                _ctx.AddToPerformance(perf);
            }

            _ctx.SaveChanges();
        }

        public int GetCountApproachOne()
        {
            return _ctx.Performance.Count(perf => perf.Action == Constants.STR_AggregateCount);
        }

        public int GetCountApproachTwo()
        {
            var result = _ctx.Performance.Where(perf => perf.Action == Constants.STR_AggregateCount);
            var list = result.ToList();

            return list.Count;
        }

        public int GetAverageApproachOne()
        {
            var result = _ctx.Performance.Where(perf => perf.Action == Constants.STR_AggregateCount).Average(perf => perf.MilliSeconds);
            return Convert.ToInt32(result);
        }

        public int GetAverageApproachTwo()
        {
            var query = from perf
                         in _ctx.Performance
                        where perf.Action == Constants.STR_AggregateCount
                        select perf.MilliSeconds;

            return Convert.ToInt32(query.Average());
        }

        public void DeleteRecordsApproachOne()
        {
            AdoNet.Aggregate.ClearAggregateCounts();
        }

        public void DeleteRecordsApproachTwo()
        {
            AdoNet.Aggregate.ClearAggregateCounts();
        }
        
        public void Dispose()
        {
            _ctx.Dispose();
        }
    }
}
